<?php
class ApiController extends BaseController {
	/**
     * QQWry.Dat文件指针
     *
     * @var resource
     */
    private $fp;

    /**
     * 第一条IP记录的偏移地址
     *
     * @var int
     */
    private $firstip;

    /**
     * 最后一条IP记录的偏移地址
     *
     * @var int
     */
    private $lastip;

    /**
     * IP记录的总条数（不包含版本信息记录）
     *
     * @var int
     */
    private $totalip;

	/**
	 * Setup the layout used by the controller.
	 *
	 * @return void
	 */
	public $testArr=array(
	    'from'=>'wechat',
	    'code'=>'A02b2650n6DV5',
	    'pid'=>'13923458888',
	    'token'=>'b15e9f7522ef99cd1135',
	    'provinceId'=>0
	    );
    private $codesArr;
    
	protected function index()
	{
		// $users = DB::table('goods_brands')->get();
		// var_dump($users);
		// exit;
		return View::make('pin.show',array(
		));
	}
	
	/*
	*channel from pc
	*/
	public function fromPc()
	{
		// $ip=$this->getLocation(Request::getClientIp());
		$ip=$this->getLocation('211.154.84.7');//test
		$pcArr['provinceId']=$this->provinceList($ip);
		$pcArr['code']=strtoupper(Input::get('code'));
		$pcArr['from']='pc';
        $pcArr['pid']='123456789';
		$data=$this->saveData($pcArr);
        $name = Redis::get('name');
		echo json_encode($data);
	}
    private function saveData($pcArr)
    {
        $this->codesArr=$this->cutData($pcArr['code']);
        // $codeFlag=$this->checkCode($this->codesArr);//检查号码的合法性
        // if ($codeFlag==0) {
        //     echo -1; //illegel code
        //     exit;
        // }
        // $usedFlag=$this->checkUse($pcArr['code']);
        // if ($usedFlag==0) {
        //     echo -2;// be used
        //     exit;
        // }

        $codeFlag=$this->checkAward();
        if ($codeFlag==0) {
           echo -3;//未中奖
           exit;
        }
        else
        {
            $awardId=Redis::hget('award_to_id',$this->codesArr['brandId'].'_'.$codeFlag);
            $awardInfo=Redis::hmget('award:'.$awardId,'award_name','award_level_name','award_total_num','payout_total_num');
            $awardProvinceId=Redis::hget('award_list_to_id',$this->codesArr['brandId'].'_'.$pcArr['provinceId'].'_'.$codeFlag);
            $awardProvinceInfo=Redis::hmget('award_list:'.$awardProvinceId,'award_num','payout_num');
            if ($awardInfo[2]>$awardInfo[3]&&$awardProvinceInfo[0]>$awardProvinceInfo[1]) {
                Redis::hincrby('award:'.$awardId,'payout_total_num',1);
                Redis::hincrby('award_list:'.$awardProvinceId,'payout_num',1);
                Redis::sadd('award_info:'.$awardId,$pcArr['code']);//各品牌下各级别奖的中奖号码记录
            }
            return $awardProvinceInfo;
        }
    }
    public function cutData($code)
    {
        $codeArr['brandId']=substr($code,0,1);
        $codeArr['batch']=substr($code,1,2);
        $codeArr['verifyCode']=substr($code,3,4);
        $codeArr['num']=substr($code,7,6);
        return $codeArr;
    }
    public function checkCode($codeArr)
    {
        $pinKeyName='pin_key_'.$codeArr['brandId'];
        if (Redis::exists($pinKeyName)) {
            $pinKey=Redis::get($pinKeyName);
        }
        else
        {
            $pinKey = DB::table('ploy_pin')->where('brand_id',$codeArr['brandId'])->pluck('pin_key');//select('pin_key')->first();
            Redis::set($pinKeyName,$pinKey);
        }
        $md5Code=$pinKey.$codeArr['num'].$codeArr['brandId'].$codeArr['batch'];
        $md5Code=substr(md5($md5Code), 0,4);
        $result=(strtoupper($md5Code)==$codeArr['verifyCode'])?1:0;
        return $result;

    }
    public function checkUse($code)
    {
        if (Redis::hexists('pin_u:'.$code,'u_time')==1) {
            $return=0;
        }
        else
        {
            // date_default_timezone_set('Asia/Shanghai');
            $ip=$this->getLocation('211.154.84.7');//test
            $pcArr['provinceId']=$this->provinceList($ip);
            $pcArr['code']=strtoupper(Input::get('code'));
            $pcArr['from']='pc';
            $pcArr['pid']='123456789';
            Redis::hmset("pin_u:{$code}",array(
                'from'=>$pcArr['from'],
                'province_id'=>$pcArr['provinceId'],
                'u_time'=>date('Y-m-d H:i:s'),
                'user_id'=>$pcArr['pid']
                ));
            $return=1;
        }
        return $return;
    }
    public function checkAward()
    {
        $levelNums=Redis::get('award_num_'.$this->codesArr['brandId']);//get nums of award
        for ($i=1; $i <= $levelNums ; $i++) { 
            $tail_num=Redis::hget('award_list:'.$i,'tail_num');
            if (strpos($tail_num,'div_')===false) 
            {
                $contractNum=substr($this->codesArr['num'],-strlen($tail_num));
                if ($contractNum==$tail_num) {//开奖号码和兑奖的尾号相等
                    return $i;
                }
            }
            else
            {
                $contractNum=substr($this->codesArr['num'],-1);
                $divNum=substr($tail_num,-1);
                $word28=$this->word28();
                $key=array_search($contractNum, $word28);//获取客户提交的号码的尾号
                $return=($key%$divNum==0)?$i:0;
                return $i;
            }
        }
        return 0;
       
    }
     /**
     * 根据所给 IP 地址或域名返回所在地区信息
     *
     * @access public
     * @param string $ip
     * @return array
     */
    private function getLocation($ip='')
    {
    	$filename ="../../public/packages/UTFWry.dat";
    	$this->fp = 0;
        if (($this->fp = fopen(dirname(__FILE__).'/'.$filename, 'rb')) !== false) {
            $this->firstip = $this->getlong();
            $this->lastip = $this->getlong();
            $this->totalip = ($this->lastip - $this->firstip) / 7;
        }
        if (!$this->fp) return null;            // 如果数据文件没有被正确打开，则直接返回空
        // $ip = gethostbyname('http://facebook.com/');   // 将输入的域名转化为IP地址
        $ip = $this->packip($ip);   // 将输入的IP地址转化为可比较的IP地址
                                                // 不合法的IP地址会被转化为255.255.255.255
        // 对分搜索
        $l = 0;                         // 搜索的下边界
        $u = $this->totalip;            // 搜索的上边界
        $findip = $this->lastip;        // 如果没有找到就返回最后一条IP记录（QQWry.Dat的版本信息）
        while ($l <= $u) {              // 当上边界小于下边界时，查找失败
            $i = floor(($l + $u) / 2);  // 计算近似中间记录
            fseek($this->fp, $this->firstip + $i * 7);
            $beginip = strrev(fread($this->fp, 4));     // 获取中间记录的开始IP地址
            // strrev函数在这里的作用是将little-endian的压缩IP地址转化为big-endian的格式
            // 以便用于比较，后面相同。
            if ($ip < $beginip) {       // 用户的IP小于中间记录的开始IP地址时
                $u = $i - 1;            // 将搜索的上边界修改为中间记录减一
            }
            else {
                fseek($this->fp, $this->getlong3());
                $endip = strrev(fread($this->fp, 4));   // 获取中间记录的结束IP地址
                if ($ip > $endip) {     // 用户的IP大于中间记录的结束IP地址时
                    $l = $i + 1;        // 将搜索的下边界修改为中间记录加一
                }
                else {                  // 用户的IP在中间记录的IP范围内时
                    $findip = $this->firstip + $i * 7;
                    break;              // 则表示找到结果，退出循环
                }
            }
        }
        //获取查找到的IP地理位置信息
        fseek($this->fp, $findip);
        $location['beginip'] = long2ip($this->getlong());   // 用户IP所在范围的开始地址
        $offset = $this->getlong3();
        fseek($this->fp, $offset);
        $location['endip'] = long2ip($this->getlong());     // 用户IP所在范围的结束地址
        $byte = fread($this->fp, 1);    // 标志字节
        switch (ord($byte)) {
            case 1:                     // 标志字节为1，表示国家和区域信息都被同时重定向
                $countryOffset = $this->getlong3();         // 重定向地址
                fseek($this->fp, $countryOffset);
                $byte = fread($this->fp, 1);    // 标志字节
                switch (ord($byte)) {
                    case 2:             // 标志字节为2，表示国家信息又被重定向
                        fseek($this->fp, $this->getlong3());
                        $location['country'] = $this->getstring();
                        fseek($this->fp, $countryOffset + 4);
                        break;
                    default:            // 否则，表示国家信息没有被重定向
                        $location['country'] = $this->getstring($byte);
                        break;
                }
                break;
            case 2:                     // 标志字节为2，表示国家信息被重定向
                fseek($this->fp, $this->getlong3());
                $location['country'] = $this->getstring();
                fseek($this->fp, $offset + 8);
               break;
            default:                    // 否则，表示国家信息没有被重定向
                $location['country'] = $this->getstring($byte);
                break;
        }
        if ($location['country'] == " CZ88.NET") {  // CZ88.NET表示没有有效信息
            $location['country'] = "未知";
        }
        fclose($this->fp);
        return $location['country'];
    }
    /**
     * 返回读取的长整型数
     *
     * @access private
     * @return int
     */
    private function getlong() {
        //将读取的little-endian编码的4个字节转化为长整型数
        $result = unpack('Vlong', fread($this->fp, 4));
        return $result['long'];
    }

    /**
     * 返回读取的3个字节的长整型数
     *
     * @access private
     * @return int
     */
    private function getlong3() {
        //将读取的little-endian编码的3个字节转化为长整型数
        $result = unpack('Vlong', fread($this->fp, 3).chr(0));
        return $result['long'];
    }

    /**
     * 返回压缩后可进行比较的IP地址
     *
     * @access private
     * @param string $ip
     * @return string
     */
    private function packip($ip) {
        // 将IP地址转化为长整型数，如果在PHP5中，IP地址错误，则返回False，
        // 这时intval将Flase转化为整数-1，之后压缩成big-endian编码的字符串
        return pack('N', intval(ip2long($ip)));
    }

    /**
     * 返回读取的字符串
     *
     * @access private
     * @param string $data
     * @return string
     */
    private function getstring($data = "") {
        $char = fread($this->fp, 1);
        while (ord($char) > 0) {        // 字符串按照C格式保存，以\0结束
            $data .= $char;             // 将读取的字符连接到给定字符串之后
            $char = fread($this->fp, 1);
        }
        return $data;
    }
    /**
	 * [provinceList description]
	 * 
	 * @return [array] [派奖区域]
	 */
	private function provinceList($ip){
		$provinceList=array(
			// 0=>"北京",1=>"天津",
			2=>"河北",3=>"山西",4=>"内蒙古",5=>"辽宁",6=>"吉林",7=>"黑龙江",8=>"上海",9=>"江苏",10=>"浙江",
			11=>"安徽",12=>"福建",13=>"江西",14=>"山东",15=>"河南",16=>"湖北",17=>"湖南省",18=>"广东",19=>"广西",20=>"海南",
			21=>"重庆",22=>"四川",23=>"贵州",24=>"云南",25=>"西藏",26=>"陕西",27=>"甘肃",28=>"青海",29=>"宁夏",30=>"新疆",
			31=>"其他地区"
			);//将32=>"香港特别行政区",33=>"澳门特别行政区"归入其他地区
		foreach ($provinceList as $key => $value) {
			if (strpos($ip, $value)!==false) {
				return $key;
			}
		}
	}
    /*
    *返回字符
    */
    public function word28()
    {
        return array(0=>"4",1=>"5",2=>"6",3=>"7",4=>"9",5=>"A",6=>"B",7=>"C",8=>"D",9=>"E",10=>"F",11=>"G",12=>"H",13=>"J",14=>"K",15=>"L",16=>"M",17=>"N",18=>"P",19=>"Q",20=>"R",21=>"S",22=>"T",23=>"U",24=>"V",25=>"W",26=>"X",27=>"Y");
    }
    

}